#ifndef __DB_CONNECTIONMGR_H__
#define __DB_CONNECTIONMGR_H__

#include <stdint.h>
#include <string>
#include <map>
#include <list>
#include "ct_mutex.h"
#include "ct_sem.h"
#include "ctSingleton.h"


class DBConnection;
class DataSource;

class DBConnectionMgr : public Singleton<DBConnectionMgr> {
public:
        DBConnectionMgr();
        ~DBConnectionMgr();

        int32_t init(int32_t max_conn);
        void release();

        int32_t loadSource(uint32_t cat, std::string db, std::string user, std::string host, std::string passwd);

        DBConnection* getConnection(uint32_t cat, uint32_t timeout_sec);
        int32_t freeConnection(uint32_t cat, DBConnection* conn);

protected:
        int32_t createPool();
private:
        uint32_t _max_conneciton_per_pool;
        std::map<uint32_t, DataSource*> _db_pools;
        ctMutex  _lock;
};


class DataSource {
public:
        DataSource(uint32_t id);
        virtual ~DataSource();

        int32_t init(uint32_t max_conn, std::string db, std::string user,
                     std::string host, std::string passwd);
        void release();

public:
        DBConnection* getConnection(uint32_t time_out);
        void releaseConnection(DBConnection*);

        uint32_t size();

protected:
        int32_t allocConnection(uint32_t number);

private:
        uint32_t _max_conn;
        uint32_t _id;

        std::list<DBConnection*>  _obj_list;
        uint32_t        _obj_number;
        uint32_t        _pop_number;
        uint32_t        _capacity;

        std::string     _db;
        std::string     _user;
        std::string     _host;
        std::string     _passwd;
        BaseSemaphore _sem;
};


#define DB_MGR DBConnectionMgr::getSingleton


#endif // __DB_CONNECTIONMGR_H__
